<template>
  <div class="container">
    <a-form
      :model="formState"
      :rules="rules"
      ref="formRef"
      class="container-form"
      layout="inline"
      @keyup.enter.native="handleAdd"
      @keyup.esc.native="handleReset"
    >
      <a-form-item label="名称">
        <a-input
          v-model:value="formState.name"
          allowClear
          placeholder="请输入"
        />
      </a-form-item>
      <a-form-item
        label="后端地址"
        name="url"
      >
        <a-input
          v-model:value="formState.url"
          allowClear
          placeholder="请输入"
        />
      </a-form-item>
      <a-form-item>
        <a-space>
          <a-button
            type="primary"
            @click="handleAdd"
          >
            <template #icon>
              <PlusOutlined />
            </template>
            新增
          </a-button>
          <a-button @click="handleReset">
            <template #icon>
              <RedoOutlined />
            </template>
            重置
          </a-button>
        </a-space>
      </a-form-item>
    </a-form>

    <a-table
      class="container-table"
      bordered
      rowKey="key"
      :scroll="{ x: 'max-content' }"
      :columns="columns"
      :data-source="dataSource"
    >
      <template #bodyCell="{ column, text, record }">
        <template v-if="['name', 'url'].includes(column.dataIndex)">
          <div>
            <a-input
              v-if="editableData[record.key]"
              v-model:value="editableData[record.key][column.dataIndex]"
              :status="column.dataIndex === 'url' ? editableData[record.key]['status'] : ''"
              style="margin: -5px 0"
              allowClear
              @change="handleInputChange(record.key, column.dataIndex)"
            />
            <template v-else>{{ text }}</template>
          </div>
        </template>
        <template v-else-if="column.dataIndex === 'operation'">
          <a-button
            type="link"
            @click="handleSelect(record)"
          >
            <template #icon>
              <SelectOutlined />
            </template>
            选择
          </a-button>
          <template v-if="editableData[record.key]">
            <a-button
              type="link"
              @click="handleSave(record.key)"
            >
              <template #icon>
                <SaveOutlined />
              </template>
              保存
            </a-button>
          </template>
          <template v-else>
            <a-button
              type="link"
              @click="handleEdit(record.key)"
            >
              <template #icon>
                <EditOutlined />
              </template>
              编辑
            </a-button>
          </template>
          <a-popconfirm
            cancel-text="取消"
            ok-text="确认"
            title="确认删除？"
            @confirm="handleDelete(record.key)"
          >
            <a-button
              danger
              type="link"
            >
              <template #icon>
                <DeleteOutlined />
              </template>
              删除
            </a-button>
          </a-popconfirm>
        </template>
      </template>
    </a-table>
  </div>
</template>
<script setup>
import { cloneDeep } from 'lodash-es'
import { useIDBKeyval } from '@vueuse/integrations/useIDBKeyval'
import { message } from 'ant-design-vue'
import { sleep } from '@/utils/common.js'
import { useSelectApiStore } from '@/store/modules/selectApi.js'

const columns = [
  {
    title: '#',
    align: 'center',
    key: 'index',
    width: '5%',
    customRender: row => row.index + 1,
  },
  {
    title: '名称',
    align: 'center',
    dataIndex: 'name',
    width: '15%',
  },
  {
    title: '后端地址',
    align: 'center',
    dataIndex: 'url',
    width: '45%',
  },
  {
    title: '操作',
    align: 'center',
    dataIndex: 'operation',
    fixed: 'right',
    width: '35%',
  },
]

const selectApiStore = useSelectApiStore()

const defaultList = [toRaw(selectApiStore.currentApi)]

const { data: dataSource } = useIDBKeyval('apiList', defaultList)

const editableData = reactive({})
const findItem = key => dataSource.value.find(item => key === item.key)
const findItemIndex = key => dataSource.value.findIndex(item => key === item.key)

const formRef = ref()
const formState = reactive({ name: '', url: '' })
const checkUrlRegex = /^(http|https):\/\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5})$/
const validateUrl = (_, value) => {
  // 使用正则表达式验证协议+IP+端口字符串
  if (checkUrlRegex.test(value)) {
    return Promise.resolve()
  } else {
    return Promise.reject('请输入合法的url')
  }
}
const rules = {
  url: [
    {
      required: true,
      validator: validateUrl,
      trigger: 'blur',
    },
  ],
}

const handleInputChange = (key, dataIndex) => {
  if (dataIndex === 'url') {
    if (checkUrlRegex.test(editableData[key][dataIndex])) {
      editableData[key]['status'] = undefined
    } else {
      editableData[key]['status'] = 'error'
    }
  }
}
const findMaxKey = computed(() => {
  let maxKey = -Infinity
  for (const item of dataSource.value) {
    if (item.key > maxKey) {
      maxKey = item.key
    }
  }
  return maxKey
})
const handleAdd = async () => {
  formRef.value
    .validate()
    .then(() => {
      dataSource.value.push({
        key: findMaxKey.value + 1,
        name: formState.name,
        url: formState.url,
      })
    })
    .catch(error => {})
}
const handleReset = () => {
  Object.assign(formState, { name: '', url: '' })
  formRef.value.resetFields()
}

const router = useRouter()
const handleSelect = async record => {
  selectApiStore.setCurrentApi(record)
  message.success('设置成功')
  await sleep(1000)
  await router.replace('/login')
}
const handleEdit = key => {
  editableData[key] = cloneDeep(findItem(key))
}
const handleSave = key => {
  if (editableData[key]['status'] === undefined) {
    Object.assign(findItem(key), editableData[key])
    delete editableData[key]
  } else {
    message.warn('请输入合法的url')
  }
}
const handleDelete = key => {
  const index = findItemIndex(key)
  dataSource.value.splice(index, 1)
  delete editableData[key]
}
</script>

<style scoped lang="scss">
.container {
  &-form {
    height: 48px;
    margin-bottom: 0;
  }
}
</style>
